Git 常用命令速查
按功能分类整理 Git 常用命令,覆盖日常开发的配置、提交、分支、远程协作与标签操作;随后讲清 git pull、git fetch、git merge 与 git rebase 四个命令的关系与分工,末尾补充两个常见问题的处理:本地 tag 与远程不一致导致同步被拒、修改已推送的提交信息。适合放在手边随查随用。
命令速查表
| 类别 | 命令 | 说明 |
|---|---|---|
| 配置 | git config --global user.name "Your Name" | 设置全局用户名 |
git config --global user.email "email@example.com" | 设置全局邮箱 | |
git config --list | 查看当前配置 | |
| 初始化 | git init | 初始化一个新的 Git 仓库 |
git clone <url> | 克隆远程仓库到本地 | |
| 查看状态 | git status | 查看工作区状态(哪些文件被修改、暂存等) |
| 添加与提交 | git add <file> | 将指定文件添加到暂存区 |
git add . | 添加当前目录所有更改到暂存区 | |
git commit -m "commit message" | 提交暂存区内容到本地仓库,并附带提交信息 | |
| 查看历史 | git log | 查看提交历史(详细) |
git log --oneline | 以单行形式显示提交历史 | |
git log --graph --all --oneline | 图形化显示所有分支的提交历史 | |
| 差异比较 | git diff | 查看工作区与暂存区之间的差异 |
git diff --staged 或 git diff --cached | 查看暂存区与最新提交之间的差异(两者等价) | |
| 撤销操作 | git checkout -- <file> | 丢弃工作区对文件的修改(恢复到最近一次暂存/提交状态) |
git reset HEAD <file> | 从暂存区移除文件(保留工作区修改) | |
git reset --hard HEAD~1 | 回退到上一个提交(会丢失最近一次提交的所有更改),慎用 | |
| 分支管理 | git branch | 列出本地所有分支 |
git branch <branch-name> | 创建新分支 | |
git checkout <branch-name> | 切换到指定分支 | |
git switch <branch-name> | (Git 2.23+)切换分支(推荐替代 checkout) | |
git checkout -b <branch-name> | 创建并切换新分支 | |
git branch -d <branch-name> | 删除已合并的分支 | |
git branch -D <branch-name> | 强制删除分支(即使未合并) | |
git merge <branch-name> | 合并指定分支到当前分支 | |
| 远程操作 | git remote -v | 查看远程仓库地址 |
git remote add origin <url> | 添加远程仓库(通常命名为 origin) | |
git push -u origin <branch> | 首次推送本地分支到远程,并设置上游跟踪 | |
git push | 推送当前分支到关联的远程分支 | |
git pull | 拉取远程更新并合并(默认相当于 fetch + merge) | |
git fetch | 获取远程更新但不合并 | |
| 标签管理 | git tag | 列出所有标签 |
git tag <tagname> | 创建轻量标签 | |
git tag -a <tagname> -m "message" | 创建带注释的标签 | |
git push origin <tagname> | 推送指定标签到远程 | |
git push origin --tags | 推送所有标签到远程 | |
| 其他实用命令 | git stash | 临时保存当前工作区和暂存区的修改 |
git stash pop | 恢复最近一次 stash 的内容 | |
git reflog | 查看 HEAD 变更记录(可用于找回「丢失」的提交) | |
git show <commit-id> | 显示某次提交的详细信息 |
pull、fetch、merge 与 rebase 的关系
git fetch 与 git pull 都用于更新本地代码,区别在于是否合并:
git fetch只获取远端仓库的分支数据,更新本地的远程跟踪分支(如origin/master),不进行合并,工作区不受影响git pull在 fetch 的基础上更进一步。官方文档的描述:把远端仓库的变更合入当前分支——当前分支落后于远端时,默认 fast-forward(快进)到远端;两者发生分歧时,需要通过--rebase或--no-rebase(或pull.rebase配置)指定调和方式
更准确地说,git pull 先执行 git fetch,然后根据配置或命令行参数调用 git merge 或 git rebase 完成分支调和,默认是 merge。
merge 与 rebase 处理分歧的结果不同。假设当前分支与远端出现如下分歧:
A---B---C master on origin
/
D---E---F---G feature
^ origin/master in your repository git pull(merge 方式)会把远端新提交(A、B、C)合并到当前分支,创建一个新的合并提交 H:
A---B---C origin/master
/ \
D---E---F---G---H feature rebase 则把当前分支上不在上游(<upstream>)中的提交(F、G)暂存到临时区域,将分支重置到上游最新提交,再把这些提交逐个重放到顶部。上游提交 C 不会被改写,被改写的是自己的 F、G(变成 F'、G'):
A---B---C---F'--G' feature
/
D---E
^ origin/master in your repository merge 保留真实的分叉历史,rebase 产出线性的历史记录。整理已有提交历史的更多操作(交互式 rebase、cherry-pick)见 Git Rebase 与 Cherry-pick 实用指南。
修改已推送的 commit 信息
场景:最近一次 commit 已经推送到远端,发现提交信息写错了,想改过来。前提是本地处于该分支最新状态。
git commit --amend进入编辑器(默认 vim):按i进入编辑模式修改提交信息,编辑完按Esc,输入:wq保存退出git push -f强制推送,覆盖远端
编辑器不一定是 vim,能保存即可,例如 nano:Ctrl+O 保存,Ctrl+X 退出。
force push 会改写远端历史:该 commit 已被他人拉取时,会给他们制造冲突,共享分支上慎用。更稳妥的写法是 git push --force-with-lease——远端在本地不知情时被更新过,推送会被拒绝,降低覆盖他人提交的风险。
本地 tag 与远程不一致导致同步被拒
场景:git pull / git fetch 时报错,同步中断:
! [rejected] v3.38.0 -> v3.38.0 (would clobber existing tag) 本地存在与远程同名的 tag,但两者指向不同的提交。常见原因是本地重新打过这个 tag(如 git tag -f),或者远程 tag 被人删掉重建过。Git 出于安全考虑拒绝覆盖本地 tag。
处理思路是删掉不一致的本地 tag,再从远程重新拉取:
- 查看远程 tag:
git ls-remote -t <remote> - 查看本地 tag:
git tag -l - 删除与远程不一致的本地 tag:
git tag -d v3.38.0 - 重新拉取远程 tag 并同步代码:
git fetch origin
git pull 关于 --prune-tags:git fetch origin --prune-tags 会按 refs/tags/*:refs/tags/* 强制拉取远程全部 tag,但单独使用时并不会清理本地多余的 tag——官方文档写明,清理仅在 --prune 同时启用时生效。要一步清掉本地已不在远程的 tag,用:
git fetch origin --prune --prune-tags 也可以写进配置长期生效:
git config fetch.prune true
git config fetch.pruneTags true 要点
- 查任意命令的权威说明用
git help <command> --hard与 force push 都是破坏性操作,执行前确认自己清楚后果- Git 2.23 起分支操作推荐用
git switch、撤销暂存推荐用git restore --staged,职责比git checkout清晰